package itsm.isperp.framework.web.paging;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

/**
 * @Title: RenderPager.java
 * @Description: 翻页器
 * @author 李焯星
 * @date 2011-9-29 上午08:47:40
 * @version V1.0
 */
public final class RenderPager {

	private static final String _paginationFormat = "显示 %s - %s 共 %s ";
	private static final String _paginationSingleFormat = "显示 %s 到 %s ";

	private static final int TODISPLAYCOUNT = 5;

	/**
	 * 
	 * 
	 * 
	 * @param url
	 * @param pb
	 * @return
	 * 
	 */
	public static final String renderHtml(String url, PagingBean pb) {
		return renderHtml(url, pb, TODISPLAYCOUNT);
	}

	public static final String renderHtml(HttpServletRequest req,
			int currentPage, int pageSize, long totalItems, int toDisplayCount,
			String pClass, String nClass) {
		String qs = req.getQueryString();
		String url = null;
		if (StringUtils.isEmpty(qs))
			url = req.getRequestURI();
		else
			url = req.getRequestURI() + "?" + qs;

		return renderHtml(url, currentPage, pageSize, totalItems,
				toDisplayCount, pClass, nClass);

	}

	public static final String renderHtml(HttpServletRequest req,
			int currentPage, int pageSize, int totalItems) {

		String qs = req.getQueryString();
		String url = null;
		if (StringUtils.isEmpty(qs))
			url = req.getRequestURI();
		else
			url = req.getRequestURI() + "?" + qs;

		return renderHtml(url, currentPage, pageSize, totalItems,
				TODISPLAYCOUNT);
	}

	public static final String renderHtml(String url, PagingBean pb,
			int toDisplayCount) {
		int currentPage = 1;
		if (pb.getStart() > pb.getPageSize()) {
			currentPage = (int) Math
					.ceil((double) (((double) (pb.getStart())) / ((double) pb
							.getPageSize())));
		}

		return renderHtml(url, currentPage, pb.getPageSize(),
				pb.getTotalItems(), toDisplayCount);

	}

	public static final String renderHtml(String url, int currentPage,
			int pageSize, long totalItems, int toDisplayCount) {
		return renderHtml(url, currentPage, pageSize, totalItems,
				toDisplayCount, "", "");
	}

	/**
	 * 
	 * 
	 * 
	 * @param url
	 * @param currentPage
	 * @param pageSize
	 * @param totalItems
	 * @param toDisplayCount
	 * @return
	 * 
	 */
	public static final String renderHtml(String url, int currentPage,
			int pageSize, long totalItems, int toDisplayCount, String pClass,
			String nClass) {

		String pageLink = "";
		String scriptRegx = "page=[\\d]+|page=";
		Pattern pattern = Pattern.compile(scriptRegx, Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(url);

		if (matcher.find()) {
			pageLink = url.replace(matcher.group(0), "page=[%page%]");
		} else if (url.indexOf("?") < 0) {
			pageLink = url + "?page=[%page%]";
		} else {
			pageLink = url + "&page=[%page%]";
		}

		currentPage = currentPage > 0 ? currentPage : 1;
		StringBuilder builder = new StringBuilder("<ul class=\"pager\">");
		renderLeftSideOfPager(builder, currentPage, pageSize, totalItems);
		render(builder, pageLink, currentPage, pageSize, totalItems,
				toDisplayCount, pClass, nClass);
		return builder.toString();
	}

	private final static String generatePageLink(String linkText,
			String pageLink, int pageNumber) {
		return String
				.format("<a href=\"%s\" class=\"ui-btn ui-shadow ui-corner-all ui-btn-inline ui-mini ui-icon-arrow-r ui-btn-icon-right\">%s</a>",
						pageLink.replace("[%page%]", Integer
								.valueOf(pageNumber).toString()), linkText);
	}

	private final static String generatePageLink(String linkText,
			String pageLink, int pageNumber, String cssClass) {
		return String.format(
				"<a href=\"%s\" class=\"" + cssClass + "\">%s</a>", pageLink
						.replace("[%page%]", Integer.valueOf(pageNumber)
								.toString()), linkText);
	}

	private static String generatePageLink(int linkText, String pageLink,
			int pageNumber) {
		return String.format("<a href=\"%s\">%s</a>", pageLink.replace(
				"[%page%]", Integer.valueOf(pageNumber).toString()), linkText);
	}

	private static String render(StringBuilder builder, String pageLink,
			int currentPage, int pageSize, long totalItems, int toDisplayCount,
			String pClass, String nClass) {

		if (totalItems <= pageSize) {
			return builder.toString();
		}
		int pageNumber = (int) Math
				.ceil((double) (((double) totalItems) / ((double) pageSize)));
		int num2 = toDisplayCount <= 0 ? 0 : 1;

		if (pageNumber < toDisplayCount) {
			toDisplayCount = pageNumber;
		}
		int num4 = toDisplayCount <= 0 ? 0 : toDisplayCount / 2;
		if (toDisplayCount > 0 && pageNumber > toDisplayCount) {
			int num5 = currentPage - num4;
			if (num5 > 1) {
				num2 = num5;
			}
			if (num5 > (pageNumber - toDisplayCount)) {
				num2 = (pageNumber - toDisplayCount) + 1;
			}
			int num6 = currentPage + num4;
			if (currentPage >= (pageNumber - num4)) {
				toDisplayCount = pageNumber;
			} else if (num6 > toDisplayCount) {
				toDisplayCount = num6;
			}
		}
		if (currentPage > 1) {
			builder.append("<li>");
			builder.append(generatePageLink("&lt;上一页", pageLink,
					currentPage - 1, pClass));
		} else {
			builder.append("<li class=\"disablepage\">&lt;上一页");
		}

		builder.append("</li>");
		if (toDisplayCount > 0) {
			if (num2 > 1) {
				builder.append("<li>");
				builder.append(generatePageLink("1", pageLink, 1));
				builder.append("</li>");
				builder.append("<li><strong>...</strong>");
				builder.append("</li>");
			}

			for (int i = num2; i <= toDisplayCount; i++) {
				if (i == currentPage) {
					builder.append(String.format(
							"<li class=\"currentpage\">%s", i));
					builder.append("</li>");
				} else {
					builder.append("<li>");
					builder.append(generatePageLink(i, pageLink, i));
					builder.append("</li>");
				}
			}
			if (toDisplayCount < pageNumber) {

				builder.append("<li><strong>...</strong>");
				builder.append("</li>");
				builder.append("<li>");
				builder.append(generatePageLink(pageNumber, pageLink,
						pageNumber));
				builder.append("</li>");
			}
		}
		if (currentPage < pageNumber) {
			builder.append("<li>");
			builder.append(generatePageLink("下一页&gt;", pageLink,
					currentPage + 1, nClass));
			builder.append("</li>");
		} else {
			builder.append("<li class=\"disablepage\">下一页&gt;");
			builder.append("</li>");
		}

		builder.append("</ul>");
		return builder.toString();
	}

	protected static void renderLeftSideOfPager(StringBuilder builder,
			int currentPage, int pageSize, long totalItems) {
		builder.append("<li class=\"pageinfo\">");
		if (pageSize == 1) {
			renderNumberOfItemsWhenThereIsOnlyOneItemPerPage(builder,
					currentPage, pageSize, totalItems);
		} else {
			renderNumberOfItemsWhenThereAreMultipleItemsPerPage(builder,
					currentPage, pageSize, totalItems);
		}
		builder.append("</li>");
	}

	protected static void renderNumberOfItemsWhenThereIsOnlyOneItemPerPage(
			StringBuilder builder, int currentPage, int pageSize,
			long totalItems) {

		builder.append(String.format(_paginationSingleFormat, (currentPage - 1)
				* pageSize + 1, totalItems));
	}

	protected static void renderNumberOfItemsWhenThereAreMultipleItemsPerPage(
			StringBuilder builder, int currentPage, int pageSize,
			long totalItems) {
		int first = (currentPage - 1) * pageSize + 1;
		int last = (int) (totalItems - first);
		if (last == 0)
			last = 1;
		else if (last >= pageSize)
			last = first + pageSize - 1;
		else
			last = (int) totalItems;
		builder.append(String
				.format(_paginationFormat, first, last, totalItems));
	}

}
